package Fuzzy;

import Parser.*;
import java.util.Vector;
import java.lang.*;

public class Defuzzyfication
{
	public Defuzzyfication(KBParser parse)
	{
		kbpParser = parse;
        // messaging aan / uit
        blnShowProgress = false;
	}


	public Vector DefuzzyVariables(Vector vctSolvedValues)
	{
		return calcDefuzzyValues(vctSolvedValues);
	}

	private String getWord(String strSet, int nr)
	{
		int huidigWord = 0;
		int i = 0;

		//Eerste en laatste spatie vervangen voor een [ of een ]
		strSet = strSet.replace('[', ' ');
		strSet = strSet.replace(']', ' ');
		strSet = strSet.trim();

		while (strSet.length() > 0)
		{
			if (i == strSet.length() || strSet.charAt(i) == '\n' ||
				strSet.charAt(i) == ' ' || strSet.charAt(i) == '\t')
			{
				//einde van huidige woord gevonden

				if (nr == huidigWord)
				{

					//huidige woord moet worden teruggegeven
					return (strSet.substring(0, i)).trim();
				}

				//nog niet het goede woord, doorgaan met volgende woord zoeken
				strSet = (strSet.substring(i, strSet.length())).trim();
				i = 0;
				huidigWord++;
			}
			i++;
		}
		return null;
	}

	//Gegevens uit het proces terug zetten naar niet-fuzzy waarden
	Vector calcDefuzzyValues(Vector vctValuesToDefuzzify)
	{
		vctDefuzzyfiedValues = new Vector();
		double A = 0.0;
		double B = 0.0;
		double C = 0.0;
		double minimum = 0.0;
		double maximum = 0.0;
		for (int x = 0; x < kbpParser.GetVariables().size(); x++)
		{
			if (getWord(kbpParser.GetVariables().toString(), x * 4).equals(vctValuesToDefuzzify.elementAt(0).toString()))
			{
				vctDefuzzyfiedValues.add(vctValuesToDefuzzify.elementAt(0).toString());

				//minimum en maximum setten a.d.h.v. de x-punten (x1 t/m x4)

				//MINIMUM
				for (int count = 0; count < kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSetCount(); count++)
				{
					if (kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX1() < minimum)
					{
						minimum = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX1();
					}

					if (kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX2() < minimum)
					{
						minimum = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX2();
					}

					if (kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX3() < minimum)
					{
						minimum = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX3();
					}

					if (kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX4() < minimum)
					{
						minimum = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX4();
					}

					//MAXIMUM
					if (kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX1() > maximum)
					{
						maximum = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX1();
					}

					if (kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX2() > maximum)
					{
						maximum = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX2();
					}

					if (kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX3() > maximum)
					{
						maximum = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX3();
					}

					if (kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX4() > maximum)
					{
						maximum = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(count).GetX4();
					}
				}

				double stapgrote = (maximum - minimum) / 25;

				for (double nr = minimum; nr <= maximumimum; nr = nr + stapgrote)
				{
					double temp = 0;
					for (int y = 0; y < kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSetCount(); y++)
					{
						double result = 0;
						double x1 = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(y).GetX1();
						double x2 = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(y).GetX2();
						double x3 = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(y).GetX3();
						double x4 = kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), (1 + (x * 4)))).getSet(y).GetX4();

						//result setten
						if (nr >= x1 && nr <= x4)
						{
							if (x2 == x3 && x3 == x4)
							{
								result = ((1 / (x4 - x1)) * (nr - x1));
							}

							if (x1 == x2 && x2 == x3)
							{
								result = 1 - (1 / (x4 - x1)) * (nr - x1);
							}

							if (x1 != x2 && x3 != x4)
							{
								if (nr < x2)
								{
									result = (1 / (x2 - x1)) * (nr - x1);
								}
								if (nr > x3)
								{
									result = 1 - ((1 / (x4 - x3)) * (nr - x3));
								}
								if (nr >= x2 && nr <= x3)
								{
									result = 1;
								}
							}
						}

						for (int k = 0; k < vctValuesToDefuzzify.size(); k++)
						{
							if (vctValuesToDefuzzify.elementAt(k).equals(kbpParser.getUniverse(getWord(kbpParser.GetVariables().toString(), ((x * 4) + 1))).getSet(y).GetName()))
							{
								double value = Double.parseDouble(vctValuesToDefuzzify.elementAt(k + 1).toString());
								if (result >= value)
								{
									if (value >= temp)
									{
										temp = value;
									}
								}
								else
								{
									if (result >= temp)
									{
										temp = result;
									}
								}
							}
						}
					}
					A = A + temp;
					B = B + (temp * nr);

					//Als messaging aan staat, bericht tonen
					if (blnShowProgress)
					{
						System.out.println("X: " + nr + " Y: " + temp + " XY: " + nr * temp);
						System.out.println("A: " + A + " B: " + B);
					}
				}
			}
		}

		//Als messaging aan staat, bericht tonen
		if (blnShowProgress)
		{
			System.out.println("** XY-Waarde na defuzzification: " + B + " **");
			System.out.println("** X-Waarde na defuzzification: " + A + " **");
		}

		C = B / A;

		//Als messaging aan staat, bericht tonen
		if (blnShowProgress)
		{
			System.out.println("** Gedefuzzyde waarde na defuzzification: " + C + " **");
		}

		String strDefuzzyfiedValue = "" + C;

		//Waarde toevoegen aan de vector
		vctDefuzzyfiedValues.add(strDefuzzyfiedValue);

		//vector met de waarden weer terug geven	
		return vctDefuzzyfiedValues;
	}
}
